package com.blinddate.utils;

import com.aliyun.oss.*;
import com.blinddate.context.BaseContext;
import com.blinddate.pojo.entity.UserInf;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.itextpdf.forms.PdfAcroForm;
import com.itextpdf.forms.fields.PdfFormField;
import com.itextpdf.forms.fields.PdfTextFormField;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.colors.DeviceRgb;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.annot.PdfWidgetAnnotation;
import com.itextpdf.kernel.pdf.canvas.parser.listener.TextChunk;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Image;
import com.itextpdf.layout.renderer.TextRenderer;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import com.itextpdf.layout.renderer.TextRenderer;
import com.itextpdf.kernel.geom.Rectangle;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.MalformedURLException;
import java.time.LocalDate;
import java.util.Hashtable;
import java.util.List;
import java.util.UUID;
import java.util.function.ToDoubleBiFunction;

@Data
@AllArgsConstructor
@Slf4j
public class AliOssUtil {

    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;
    private String mpdf;
    private String wmpdf;
    private String font;
    private String bigfont;


    /**
     * 文件上传
     *
     * @param bytes
     * @param objectName
     * @return
     */
    public String upload(byte[] bytes, String objectName) {

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // 创建PutObject请求。
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

        //文件访问路径规则 https://BucketName.Endpoint/ObjectName
        StringBuilder stringBuilder = new StringBuilder("https://");
        stringBuilder
                .append(bucketName)
                .append(".")
                .append(endpoint)
                .append("/")
                .append(objectName);

        log.info("文件上传到:{}", stringBuilder.toString());

        return stringBuilder.toString();
    }

    public String pdf(UserInf userInf, String s) throws IOException {
        String pdfmbpath= UUID.randomUUID().toString()+".pdf";
        String localpdf=UUID.randomUUID().toString()+".pdf";
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        String sex=new String();
        //分男 女 下载不同的模板
        File templateFile =null;
        if(userInf.getGender()==1){
            sex="男:";
            // 下载模板文件到本地
            InputStream templateInputStream = ossClient.getObject(bucketName, mpdf).getObjectContent();
            templateFile = new File(pdfmbpath);
            OutputStream templateOutputStream = new FileOutputStream(templateFile);
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = templateInputStream.read(buffer)) != -1) {
                templateOutputStream.write(buffer, 0, bytesRead);
            }
            templateInputStream.close();
            templateOutputStream.close();
        }else {
            sex="女:";
            // 下载模板文件到本地
            InputStream templateInputStream = ossClient.getObject(bucketName, wmpdf).getObjectContent();
            templateFile = new File(pdfmbpath);
            OutputStream templateOutputStream = new FileOutputStream(templateFile);
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = templateInputStream.read(buffer)) != -1) {
                templateOutputStream.write(buffer, 0, bytesRead);
            }
            templateInputStream.close();
            templateOutputStream.close();
        }
        LocalDate localDate=LocalDate.now();
        int year=localDate.getYear()- userInf.getAge();
        String a=Integer.toString(year)+"年";
        String age=a.substring(2);

        String num=LocalDate.now().toString().replace("-","");
        String id=num+userInf.getUserId().toString();

        StringBuilder sb0=new StringBuilder(userInf.getPhone());
        String phone= String.valueOf(sb0.replace(3,7,"****"));
        PdfDocument pdfDocument = new PdfDocument(new PdfReader(templateFile), new PdfWriter(localpdf));
        PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDocument, false);
        PdfFont Font = PdfFontFactory.createFont(font);
        PdfFont bigFont = PdfFontFactory.createFont(bigfont);
        DeviceRgb color = new DeviceRgb(0, 0, 0);
        DeviceRgb color1=null;
        if(userInf.getGender()==1){
            color1=new DeviceRgb(127, 182, 232);
        }else{
            color1=new DeviceRgb(255,176,170);
        }
        //文本填充
        form.getFormFields().get("id").setValue(id).setColor(color).setFont(bigFont).setFontSize(18);
        form.getFormFields().get("age").setValue(age).setColor(color1).setFont(Font).setFontSize(50);
        if(userInf.getPlace()!=null){form.getFormFields().get("habitation").setValue("现居:"+userInf.getPlace().replace(" ", "")).setColor(color).setFont(bigFont).setFontSize(18);}
        else {
            form.getFormFields().get("habitation").setValue("现居:"+"未完善").setColor(color).setFont(bigFont).setFontSize(18);
        }
       if(userInf.getHeight()!=null){form.getFormFields().get("height").setValue("身高:"+userInf.getHeight().toString()).setColor(color).setFont(bigFont).setFontSize(18);}
       else {
           form.getFormFields().get("height").setValue("身高:"+"未完善").setColor(color).setFont(bigFont).setFontSize(18);
       }
        form.getFormFields().get("phone").setValue("扫码打电话:"+phone).setColor(color).setFont(bigFont).setFontSize(18);
        if(userInf.getEducation()!=null){form.getFormFields().get("education").setValue("学历:"+userInf.getEducation()).setColor(color).setFont(bigFont).setFontSize(18);}
        else {
            form.getFormFields().get("education").setValue("学历:"+"未完善").setColor(color).setFont(bigFont).setFontSize(18);
        }
        form.getFormFields().get("gender").setValue(sex).setColor(color1).setFont(Font).setFontSize(50);
        if(userInf.getIncome()!=null){form.getFormFields().get("income").setValue("收入:"+userInf.getIncome().toString()).setColor(color).setFont(bigFont).setFontSize(18);}
        else {
            form.getFormFields().get("income").setValue("收入:"+"未完善").setColor(color).setFont(bigFont).setFontSize(18);
        }
        if(userInf.getCareer()!=null){form.getFormFields().get("career").setValue("职业:"+userInf.getCareer()).setColor(color).setFont(bigFont).setFontSize(18);}
        else {
            form.getFormFields().get("career").setValue("职业:"+"未完善").setColor(color).setFont(bigFont).setFontSize(18);
        }
        if(userInf.getHome()!=null){form.getFormFields().get("home").setValue("家乡:"+userInf.getHome().replace(" ", "")).setColor(color).setFont(bigFont).setFontSize(18);}
        else {
            form.getFormFields().get("home").setValue("家乡:"+"未完善").setColor(color).setFont(bigFont).setFontSize(18);
        }
        if(userInf.getRealEstate()!=null){form.getFormFields().get("real_estate").setValue("房产:"+userInf.getRealEstate()).setColor(color).setFont(bigFont).setFontSize(18);}
        else {
            form.getFormFields().get("real_estate").setValue("房产:"+"未完善").setColor(color).setFont(bigFont).setFontSize(18);
        }
        if(userInf.getVehicle()!=null){form.getFormFields().get("vehicle").setValue("车产:"+userInf.getVehicle()).setColor(color).setFont(bigFont).setFontSize(18);}
        else {
            form.getFormFields().get("vehicle").setValue("车产:"+"未完善").setColor(color).setFont(bigFont).setFontSize(18);
        }
        if(userInf.getSchool()!=null){form.getFormFields().get("school").setValue("学校:"+userInf.getSchool()).setColor(color).setFont(bigFont).setFontSize(18);}
        else {
            form.getFormFields().get("school").setValue("学校:"+"未完善").setColor(color).setFont(bigFont).setFontSize(18);
        }
        if(userInf.getShape()!=null){form.getFormFields().get("shape").setValue("体形:"+userInf.getShape()).setColor(color).setFont(bigFont).setFontSize(18);}
        else {
            form.getFormFields().get("shape").setValue("体形:"+"未完善").setColor(color).setFont(bigFont).setFontSize(18);
        }
        if(userInf.getMarriage()!=null){form.getFormFields().get("marriage").setValue("婚姻:"+userInf.getMarriage()).setColor(color).setFont(bigFont).setFontSize(18);}
        else {
            form.getFormFields().get("marriage").setValue("婚姻:"+"未完善").setColor(color).setFont(bigFont).setFontSize(18);
        }
        if(userInf.getMarry()!=null){form.getFormFields().get("marry").setValue("希望何时结婚:"+userInf.getMarry()).setColor(color).setFont(bigFont).setFontSize(18);}
        else {
            form.getFormFields().get("marry").setValue("希望何时结婚:"+"未完善").setColor(color).setFont(bigFont).setFontSize(18);
        }
        if(userInf.getSelectAge()!=null){form.getFormFields().get("select_age").setValue("年龄:"+userInf.getSelectAge().toString()).setColor(color).setFont(bigFont).setFontSize(18);}
        else {
            form.getFormFields().get("select_age").setValue("年龄:"+"未完善").setColor(color).setFont(bigFont).setFontSize(18);
        }
        if(userInf.getSelectEducation()!=null){form.getFormFields().get("select_education").setValue("学历:"+userInf.getSelectEducation()).setColor(color).setFont(bigFont).setFontSize(18);}
        else {
            form.getFormFields().get("select_education").setValue("学历:"+"未完善").setColor(color).setFont(bigFont).setFontSize(18);
        }
        if(userInf.getSelectHeight()!=null){form.getFormFields().get("select_height").setValue("身高:"+userInf.getSelectHeight().toString()).setColor(color).setFont(bigFont).setFontSize(18);}
        else {
            form.getFormFields().get("select_height").setValue("身高:"+"未完善").setColor(color).setFont(bigFont).setFontSize(18);
        }
        PdfWidgetAnnotation widget = form.getFormFields().get("self_intro").getWidgets().get(0);
//        PdfTextFormField pdfTextFormField= (PdfTextFormField) form.getFormFields().get("self_intro");
//        pdfTextFormField.setFontSize(12);
//        pdfTextFormField.setJustification(PdfFormField.ALIGN_LEFT);
//        String longText = "This is a long text that needs to be wrapped automatically in the form field.";
//        pdfTextFormField.setValue(String.valueOf(new PdfString(userInf.getSelfIntro())));
        /**
         * 手动处理换行问题
         */
        if(userInf.getSelfIntro()!=null) {
            String value = userInf.getSelfIntro();

            float fontSize = 18;
            float maxWidth = 504;// 设置最大宽度
            float currentWidth = 0;
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < value.length(); i++) {
                char c = value.charAt(i);
                float characterWidth = bigFont.getWidth(c, fontSize);
                System.out.println(characterWidth);
                if (characterWidth == 9) {
                    characterWidth = 8;
                }
                if (currentWidth + characterWidth <= maxWidth && c != '\n') {
                    sb.append(c);
                    currentWidth += characterWidth;
                } else if (c == '\n') {
                    sb.append(c);
                    currentWidth = characterWidth;
                } else {
                    sb.append("\n").append(c); // 换行
                    currentWidth = characterWidth;
                }
            }
            String filledValue = sb.toString();
            form.getField("self_intro").setValue(filledValue).setFont(bigFont).setFontSize(18);
        }

        //form.getFormFields().get("self_intro").setValue(userInf.getSelfIntro()).setColor(color).setFont(Font);

        //填充图片
        PdfFormField formField= form.getField("image");
        Image image=addimage(formField,userInf.getCodeSrc());
        //获取文档对象 将图像添加
        Document document=new Document(pdfDocument);
        document.add(image);
        form.flattenFields();
        document.close();
        pdfDocument.close();
        InputStream resultInputStream = new FileInputStream(localpdf);
        ossClient.putObject(bucketName, s, resultInputStream);
        resultInputStream.close();

        // 删除本地文件
        templateFile.delete();
        new File(localpdf).delete();

        // 关闭 OSS 客户端
        ossClient.shutdown();
        StringBuilder stringBuilder = new StringBuilder("https://");
        stringBuilder
                .append(bucketName)
                .append(".")
                .append(endpoint)
                .append("/")
                .append(s);
        String path=stringBuilder.toString();
        log.info("pdf文件上传到:{}", path);
        return path;
    }

    /**
     * 填充图片的函数
     * @param pdfFormField
     * @param imagesrc
     * @return
     */
    private Image addimage(PdfFormField pdfFormField,String imagesrc){
        List<PdfWidgetAnnotation> widgets=pdfFormField.getWidgets();
        PdfWidgetAnnotation widget=widgets.get(0);
        //域左下角顶点坐标
        float x1=widget.getRectangle().getAsNumber(0).floatValue();
        float y1=widget.getRectangle().getAsNumber(1).floatValue();
        //域右上角顶点坐标
        float x2=widget.getRectangle().getAsNumber(2).floatValue();
        float y2=widget.getRectangle().getAsNumber(3).floatValue();
        //域宽高
        float fieldWidth=x2-x1;
        float fieldHeight=y2-y1;
        //创建图片对象
        Image im= null;
        try {
            im = new Image(ImageDataFactory.create(imagesrc));
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        }
        Image image=im.scaleToFit(fieldWidth,fieldHeight);//图片自适应缩放
        //获取图片的自适应缩放后的宽高
        float scaleWidth=image.getImageScaledWidth();
        float scaleHeight=image.getImageScaledHeight();
        //计算图片居中位置
        float centerX=x1+(fieldWidth/2)-(scaleWidth/2);
        float centerY=y1+(fieldHeight/2)-(scaleHeight/2);
        image.setFixedPosition(centerX,centerY);
        return image;
    }
//    public String ewm(){
//        String path=null;
//        try {
//            path = generateCode(BaseContext.getCurrentId().toString());
//            if (path!=null) {
//               log.info("成功生成二维码 路径为:{}", path);
//            }
//
//        } catch (WriterException | IOException e) {
//            System.err.println("生成二维码失败");
//            e.printStackTrace();
//        }
//        return path;
//    }
//    private static final int BLACK = 0xFF000000;
//    private static final int WHITE = 0xFFFFFFFF;
//    public  String generateCode(String userid) throws WriterException, IOException {
//        // 这里是URL，扫描之后就跳转到这个界面
//        String text = userid;
//        String ewmpath = "."; // 图片生成的位置
//        int width = 400;
//        int height = 400;
//        // 二维码图片格式
//        String format = "jpg";
//        // 设置编码，防止中文乱码
//        Hashtable<EncodeHintType, Object> ht = new Hashtable<EncodeHintType, Object>();
//        ht.put(EncodeHintType.CHARACTER_SET, "UTF-8");
//        // 设置二维码参数(编码内容，编码类型，图片宽度，图片高度,格式)
//        BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, ht);
//        // 生成二维码(定义二维码输出服务器路径)
//        File outputFile = new File(ewmpath);
//        if (!outputFile.exists()) {
//            // 创建文件夹
//            outputFile.mkdir();
//        }
//
//        int b_width = bitMatrix.getWidth();
//        int b_height = bitMatrix.getHeight();
//        // 建立图像缓冲器
//        BufferedImage image = new BufferedImage(b_width, b_height, BufferedImage.TYPE_3BYTE_BGR);
//        for (int x = 0; x < b_width; x++) {
//            for (int y = 0; y < b_height; y++) {
//                image.setRGB(x, y, bitMatrix.get(x, y) ? BLACK : WHITE);
//            }
//        }
//        String name= "/"+UUID.randomUUID().toString()+".";
//        // 生成二维码
//        File file=new File(ewmpath + name + format);
//        ImageIO.write(image, format,file);
//        //上传到oss
//        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
//        String s = UUID.randomUUID().toString()+".jpg";
//        ossClient.putObject(bucketName,s,file);
//        ossClient.shutdown();
//        // 二维码的名称
//        file.delete();
//        StringBuilder stringBuilder = new StringBuilder("https://");
//        stringBuilder
//                .append(bucketName)
//                .append(".")
//                .append(endpoint)
//                .append("/")
//                .append(s);
//        String path=stringBuilder.toString();
//        return path;
//    }

    /**
     * 删除上传的无效照片
     * @param list
     */
    public void delete(List<String> list){
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        String prefix = "https://wcf-test.oss-cn-beijing.aliyuncs.com/";
        for (String s : list) {
            String result=s.replaceFirst(prefix,"");
            log.info("{}",result);
            ossClient.deleteObject(bucketName,result);
        }
        ossClient.shutdown();
    }

}

